﻿
//命名空间
using System;
using System.Drawing;
using System.Windows.Forms;
using n_ctext;

namespace n_UnitTreeView
{
//语法树类
public static class UnitTreeView
{
	public static TreeView UnitTree;
	static bool isNotUpData;
	static string Expandednodes;
	static Timer timer;
	static CTextBox ctext;
	
	//初始化
	public static TreeView Init()
	{
		UnitTree = new TreeView();
		UnitTree.Visible = true;
		UnitTree.Dock = DockStyle.Fill;
		UnitTree.DrawNode += NodeDraw;
		UnitTree.AfterCollapse += new TreeViewEventHandler( TreeView1AfterCollapse );
		UnitTree.AfterExpand += new TreeViewEventHandler( TreeView1AfterExpand );
		Expandednodes = " ";  //当前已经展开的元件节点
		isNotUpData = false;
		
		UnitTree.Nodes.Add( "test" );
		
		timer = new Timer();
		timer.Enabled = false;
		timer.Interval = 1;
		timer.Tick += new EventHandler( Timer_Tick );
		
		return UnitTree;
	}
	
	//清空
	public static void Clear()
	{
		UnitTree.Nodes.Clear();
		UnitTree.Refresh();
	}
	
	//添加节点
	public static void AddNode( TreeNode n )
	{
		UnitTree.Nodes.Add( n );
	}
	
	//全部展开语法树
	public static void ExpandAll()
	{
		isNotUpData = true;
		UnitTree.ExpandAll();
		isNotUpData = false;
	}
	
	//全部折叠语法树
	public static void CollapseAll()
	{
		isNotUpData = true;
		UnitTree.CollapseAll();
		isNotUpData = false;
	}
	
	//恢复原状
	public static void ComeBack()
	{
		isNotUpData = true;
		UnitTree.CollapseAll();
		foreach( TreeNode node in UnitTree.Nodes ) {
			if( Expandednodes.IndexOf( ";" + node.Text + ";" ) != -1 ) {
				node.Expand();
				foreachNodeExpand( node );
			}
		}
		UnitTree.Refresh();
		isNotUpData = false;
	}
	
	//转向选择的节点目标
	public static void GotoSelectedNode( CTextBox text )
	{
		ctext = text;
		timer.Enabled = true;
	}
	
	//遍历一个节点的所有应展开节点
	static void foreachNodeExpand( TreeNode Fnode )
	{
		foreach( TreeNode node in Fnode.Nodes ) {
			if( Expandednodes.IndexOf( ";" + Fnode.Text + "-" + node.Text + ";" ) != -1 ) {
				node.Expand();
				foreachNodeExpand( node );
			}
		}
	}
	
	//遍历一个节点的所有节点,记录是否展开
	static void foreachNodeAddName( TreeNode Fnode )
	{
		foreach( TreeNode node in Fnode.Nodes ) {
			if( !node.IsExpanded ) {
				continue;
			}
			Expandednodes += Fnode.Text + "-" + node.Text + ";";
			foreachNodeAddName( node );
		}
	}
	
	//重绘
	static void NodeDraw(object sender, DrawTreeNodeEventArgs e)
	{
		if( e.Bounds.Location.X < 10 ) {
			return;
		}
		//绘制文字
		Color UnitColor = Color.Navy;
		Color FunctionColor = Color.Green;
		Color VarColor = Color.Olive;
		Color ConstColor = Color.Gray;
		string Type = e.Node.Name.Split( ',' )[ 1 ];
		switch( Type ) {
			case "unit": Set( e, UnitColor ); break;
			case "PublicFunctionSet": Set( e, FunctionColor ); break;
			case "PrivateFunctionSet": Set( e, FunctionColor ); break;
			case "PublicVarSet": Set( e, VarColor ); break;
			case "PrivateVarSet": Set( e, VarColor ); break;
			case "PublicConstSet": Set( e, ConstColor ); break;
			case "PrivateConstSet": Set( e, ConstColor ); break;
			
			case "PublicFunction": Function( e ); break;
			case "PrivateFunction": Function( e ); break;
			case "PublicVar": VarAndConst( e ); break;
			case "PrivateVar": VarAndConst( e ); break;
			case "PublicConst": VarAndConst( e ); break;
			case "PrivateConst": VarAndConst( e ); break;
			
			default: break;
		}
	}
	
	//折叠事件
	static void TreeView1AfterCollapse(object sender, TreeViewEventArgs e)
	{
		if( isNotUpData ) {
			return;
		}
		Expandednodes = ";";
		foreach( TreeNode node in UnitTree.Nodes ) {
			if( !node.IsExpanded ) {
				continue;;
			}
			Expandednodes += node.Text + ";";
			foreachNodeAddName( node );
		}
	}
	
	//展开事件
	static void TreeView1AfterExpand(object sender, TreeViewEventArgs e)
	{
		if( isNotUpData ) {
			return;
		}
		Expandednodes = ";";
		foreach( TreeNode node in UnitTree.Nodes ) {
			if( !node.IsExpanded ) {
				continue;;
			}
			Expandednodes += node.Text + ";";
			foreachNodeAddName( node );
		}
	}
	
	//绘制集合名称
	static void Set( DrawTreeNodeEventArgs e, Color c )
	{
		e.Graphics.DrawString( e.Node.Text, UnitTree.Font, new SolidBrush( c ),
		                      e.Bounds.Location.X, e.Bounds.Location.Y );
	}
	
	//绘制函数
	static void Function( DrawTreeNodeEventArgs e )
	{
		int RightPad = e.Node.Text.LastIndexOf( ")" );
		int LeftPad = e.Node.Text.LastIndexOf( "(" );
		string ReturnTypeAndName = e.Node.Text.Remove( LeftPad );
		string VarTypeSet = e.Node.Text.Substring( LeftPad + 1, RightPad - LeftPad - 1 );
		
		int SplitIndex = ReturnTypeAndName.LastIndexOf( ' ' );
		string ReturnType = ReturnTypeAndName.Remove( SplitIndex );
		string Name = ReturnTypeAndName.Remove( 0, SplitIndex + 1 );
		
		int Mod = 5;
		float Offset = 0;
		//绘制返回类型
		e.Graphics.DrawString( ReturnType, UnitTree.Font, Brushes.Blue,
		                      e.Bounds.Location.X, e.Bounds.Location.Y );
		Offset += e.Graphics.MeasureString( ReturnType, UnitTree.Font ).Width - Mod;
		
		//绘制函数名
		e.Graphics.DrawString( " " + Name, UnitTree.Font, Brushes.DarkSlateGray,
		                      e.Bounds.Location.X + Offset, e.Bounds.Location.Y );
		Offset += e.Graphics.MeasureString( " " + Name, UnitTree.Font ).Width - Mod;
		
		//绘制左小括号
			e.Graphics.DrawString( "(", UnitTree.Font, Brushes.DarkSlateGray,
		                     	 	e.Bounds.Location.X + Offset, e.Bounds.Location.Y );
		Offset += e.Graphics.MeasureString( "(", UnitTree.Font ).Width - Mod;
		
		//绘制形参集合
		string[] TypeCut = VarTypeSet.Split( ',' );
		for( int i = 0; i < TypeCut.Length; ++i ) {
			
			//绘制形参
			e.Graphics.DrawString( TypeCut[ i ], UnitTree.Font, Brushes.Blue,
		                     	 	e.Bounds.Location.X + Offset, e.Bounds.Location.Y );
			Offset += e.Graphics.MeasureString( TypeCut[ i ], UnitTree.Font ).Width - Mod;
			
			//绘制逗号
			if( i == TypeCut.Length - 1 ) {
				break;
			}
			e.Graphics.DrawString( ",", UnitTree.Font, Brushes.DarkSlateGray,
		                     	 	e.Bounds.Location.X + Offset, e.Bounds.Location.Y );
			Offset += e.Graphics.MeasureString( ",", UnitTree.Font ).Width - Mod;
		}
		//绘制右小括号
		e.Graphics.DrawString( ")", UnitTree.Font, Brushes.DarkSlateGray,
		                     	e.Bounds.Location.X + Offset, e.Bounds.Location.Y );
	}
	
	//绘制变量和常量
	static void VarAndConst( DrawTreeNodeEventArgs e )
	{
		int SplitIndex = e.Node.Text.LastIndexOf( ' ' );
		string Type = e.Node.Text.Remove( SplitIndex );
		string Name = e.Node.Text.Remove( 0, SplitIndex + 1 );
		
		float Offset = 0;
		//绘制类型
		e.Graphics.DrawString( Type, UnitTree.Font, Brushes.Blue,
		                      e.Bounds.Location.X, e.Bounds.Location.Y );
		
		Offset += e.Graphics.MeasureString( Type, UnitTree.Font ).Width;
		//绘制名称
		e.Graphics.DrawString( Name, UnitTree.Font, Brushes.DarkSlateGray,
		                      e.Bounds.Location.X + Offset,
		                      e.Bounds.Location.Y );
	}

	//到时间
	static void Timer_Tick( object sender, EventArgs e )
	{
		timer.Enabled = false;
		string SLine = UnitTree.SelectedNode.Name.Split( ',' )[ 0 ];
		//跳过容器类
		if( SLine == "!" ) {
			return;
		}
		int Line = int.Parse( SLine );
		int Start = 0;
		try {
			Start = ctext.GetFirstCharIndexFromLine( Line );
		}
		catch {
			A.CodeErrBox.Run( "发现无效的函数定位点,可能是以下原因:" +
			                "\n1 目标文件已关闭;\n2 修改后未编译更新;\n3 其他原因." );
			return;
		}
		if( Start == -1 ) {
			A.CodeErrBox.Run( "发现无效的函数定位点,可能是以下原因:" +
			                "\n1 目标文件已关闭;\n2 修改后未编译更新;\n3 其他原因." );
			return;
		}
		ctext.Focus();
		ctext.SelectBackLine( Line );
		ctext.Focus();
	}
}
}
